<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>如何使用ui.router？</title>

    <link rel="stylesheet" href="../css/reveal/reveal.css">

    <!-- PPT主题，可以在/css/reveal/theme/中选择其他主题，目前暂时只能使用该模板 -->
    <link rel="stylesheet" href="../css/reveal/theme/ptt.css">

    <!-- syntax highlighting 代码高亮主题 -->
    <link rel="stylesheet" href="../lib/reveal/css/zenburn.css">

    <!-- 打印和PDF输出样式 -->
    <script>
        var link = document.createElement('link');
        link.rel = 'stylesheet';
        link.type = 'text/css';
        link.href = window.location.search.match(/print-pdf/gi) ? '../css/reveal/print/pdf.css' : '../css/reveal/print/paper.css';
        document.getElementsByTagName('head')[0].appendChild(link);
    </script>
</head>
<body>
<!--<img src="../img/demo/logo.png" alt="" usemap="#pttmap" class="base-logo">-->
<map name="pttmap">
    <area shape="rect" coords="0,0,276,58" href="http://www.jnshu.com" alt="" target="_blank"/>
</map>
<div class="reveal">
    <div class="slides">
        <section>
            <h2>【JS-6】</h2>
            <h3>如何使用ui-router？</h3>
            <p>分享人：王栋</p>
        </section>

        <section>
            <p>目录</p>
            <p>1.背景介绍</p>
            <p>2.知识剖析</p>
            <p>3.常见问题</p>
            <p>4.解决方案</p>
            <p>5.编码实战</p>
            <p>6.扩展思考</p>
            <p>7.参考文献</p>
            <p>8.更多讨论</p>
        </section>
        <section>
            <h3>一.背景介绍</h3>
        </section>


        <section>
            <p>angular路由</p>

            <p style="text-align:left">路由(route)，几乎所有的MVC(VM)框架都应该具有的特性，因为它是前端构建单页面应用(SPA)必不可少的组成部分。</p>

            <p style="text-align:left">那么，对于angular而言，它自然也有内置的路由模块：叫做ngRoute。</p>

            <p style="text-align:left">不过，大家很少用它，因为它的功能太有限，往往不能满足开发需求！！</p>

            <p style="text-align:left">于是，一个基于ngRoute开发的第三方路由模块，叫做ui.router，受到了大家的“追捧”。
                ngRoute vs ui.router</p>

        </section>
        <section>
            <p style="text-align:left">首先，无论是使用哪种路由，作为框架额外的附加功能，它们都将以模块依赖的形式被引入，简而言之就是：在引入路由源文件之后，你的代码应该这样写(以ui.router为例)：</p>
            <pre>
    <code>
angular.module("myApp", ["ui.router"]); // myApp为自定义模块，依赖第三方路由模块ui.router

    </code>
</pre>

            <p style="text-align:left">这样做的目的是：在程序启动(Angular)的时候，加载依赖模块(如：ui.router)，将所有挂载在该模块的服务(provider)，指令(directive)，过滤器(filter)等都进行注册，那么在后面的程序中便可以调用了。</p>

            <p style="text-align:left">说到这里，就得看看ngRoute模块和ui.router模块各自都提供了哪些服务，哪些指令？
            </p>
        </section>
        <section>
            <h3>二.知识剖析</h3>
        </section>
        <section>
  <pre>
      <code>
    ngRoute
        $routeProvider(服务提供者) ——— 对应于下面的urlRouterProvider和stateProvider
        $route(服务) ——— 对应于下面的urlRouter和state
        $routeParams(服务) ——— 对应于下面的stateParams
        ng-view(指令) ——— 对应于下面的ui-view

    ui.router
        $urlRouterProvider(服务提供者) ——— 用来配置路由重定向
        $urlRouter(服务)
        $stateProvider(服务提供者) ——— 用来配置路由
        $state(服务) ——— 用来显示当前路由状态信息，以及一些路由方法（如：跳转）
        $stateParams(服务) ——— 用来存储路由匹配时的参数
        ui-view(指令) ——— 路由模板渲染，对应的dom相关联
        ui-sref(指令)
      </code>
  </pre>

            <p style="text-align:left">(注：服务提供者：用来提供服务实例和配置服务。)</p>
        </section>

        <section>
            <p style="text-align:left">这样一看，其实ui.router和ngRoute大体的设计思路，对应的模块划分都是一致的(毕竟是同一个团队开发)，不同的地方在于功能点的实现和增强。</p>

            <p style="text-align:left">那么问题来了：ngRoute弱在哪些方面，ui.router怎么弥补了这些方面?
            </p>

            <p style="text-align:left">这里，列举两个最重要的方面来说(其他细节，后面再说)：</p>

            <p style="text-align:left">多视图</p>
            <p style="text-align:left">嵌套视图</p>
        </section>
        <section>
            <h3>三.常见问题</h3>
        </section>
        <section>
            <p style="text-align:left">多视图</p>

            <p style="text-align:left">多视图：页面可以显示多个动态变化的不同区块。</p>

            <p style="text-align:left">这样的业务场景是有的：</p>

            <p style="text-align:left">比如：页面一个区块用来显示页面状态，另一个区块用来显示页面主内容，当路由切换时，页面状态跟着变化，对应的页面主内容也跟着变化。</p>
        </section>

        <section>
            <p style="text-align:left">首先，我们尝试着用ngRoute来做：</p>
            <pre>
    <code>
html

<div ng-view>区块1</div>
<div ng-view>区块2</div>

js

$routeProvider
    .when('/', {
        template: 'hello world'
    });
    </code>
</pre>

        </section>

        <section>
            <p style="text-align:left">我们在html中利用ng-view指令定义了两个区块，于是两个div中显示了相同的内容，这很合乎情理，但却不是我们想要的，但是又不能为力，因为，在ngRoute中：</p>

            <p style="text-align:left">视图没有名字进行唯一标志，所以它们被同等的处理。</p>
            <p style="text-align:left">路由配置只有一个模板，无法配置多个。</p>
        </section>
        <section>
            <p style="text-align:left">ok，针对上述两个问题，我们尝试用ui.router来做：</p>
            <pre>
    <code>
html

  <div ui-view></div>
  <div ui-view="status"></div>

js

$stateProvider
    .state('home', {
        url: '/',
        views: {
            '': {
                template: 'hello world'
            },
            'status': {
                template: 'home page'
            }
        }
    });
    </code>
</pre>
        </section>
        <section>

            <p style="text-align:left">这次，结果是我们想要的，两个区块，分别显示了不同的内容，原因在于，在ui.router中：</p>

            <p style="text-align:left">可以给视图命名，如：ui-view=”status”。</p>
            <p style="text-align:left">可以在路由配置中根据视图名字(如：status)，配置不同的模板（其实还有controller等）。</p>



        </section>

        <section>
            <p style="text-align:left">嵌套视图</p>

            <p style="text-align:left">嵌套视图：页面某个动态变化区块中，嵌套着另一个可以动态变化的区块。</p>

            <p style="text-align:left">这样的业务场景也是有的：</p>

            <p style="text-align:left">比如：页面一个主区块显示主内容，主内容中的部分内容要求根据路由变化而变化，这时就需要另一个动态变化的区块嵌套在主区块中。</p>
        </section>


        <section>
        <p style="text-align:left">其实，嵌套视图，在html中的最终表现就像这样：</p>
        <pre>
        <code>
        <div ng-view>
        I am parent
        <div ng-view>I am child</div>
        </div>

        转成javascript，我们会在程序里这样写：

        $routeProvider
        .when('/', {
        template: 'I am parent <div ng-view>I am child</div>'
        });
        </code>
        </pre>

        </section>

        <section>
        <p style="text-align:left">倘若，你真的用ngRoute这样写，你会发现浏览器崩溃了，因为在ng-view指令link的过程中，代码会无限递归下去。</p>

        <p style="text-align:left">那么造成这种现象的最根本原因：路由没有明确的父子层级关系！</p>

        <p style="text-align:left">看看ui.router是如何解决这一问题的？</p>
        <!--<pre>-->
        <!--<code>-->
        <!--$stateProvider-->
        <!--.state('parent', {-->
        <!--abstract: true,-->
        <!--url: '/',-->
        <!--template: 'I am parent <div ui-view></div>'-->
        <!--})-->
        <!--.state('parent.child', {-->
        <!--url: '',-->
        <!--template: 'I am child'-->
        <!--});        -->
        <!--</code>-->
        <!--</pre>-->

        </section>

        <section>
        <p style="text-align:left"> 巧妙地，通过parent与parent.child来确定路由的父子关系，从而解决无限递归问题。</p>
        <p style="text-align:left">另外子路由的模板最终也将被插入到父路由模板的div[ui-view]中去，从而达到视图嵌套的效果。</p>

        <!--<p style="text-align:left">记住下面是ui.router用到的所有指令</p>-->
        <!--<pre>-->
        <!--<code>-->
        <!--ui.router-->
        <!--$urlRouterProvider(服务提供者) ——— 用来配置路由重定向-->
        <!--$urlRouter(服务)-->
        <!--$stateProvider(服务提供者) ——— 用来配置路由-->
        <!--$state(服务) ——— 用来显示当前路由状态信息，以及一些路由方法（如：跳转）-->
        <!--$stateParams(服务) ——— 用来存储路由匹配时的参数-->
        <!--ui-view(指令) ——— 路由模板渲染，对应的dom相关联-->
        <!--ui-sref(指令)        -->
        <!--</code>-->
        <!--</pre>-->

        </section>
        <section>
            <h3>四.解决方案</h3>
        </section>


        <section>

<pre>
    <code>
参数：
name：状态的名称。
stateConfig：状态配置对象。配置具有以下各项属性（全部属性，看一下好了）：
template： string/function，html模板字符串，或者一个返回html模板字符串的函数。
templateUrl：string/function，模板路径的字符串，或者返回模板路径字符串的函数。
templateProvider：function，返回html模板字符串或模板路径的服务。
controller：string/function，新注册一个控制器函数或者一个已注册的控制器的名称字符串。
controllerProvider：function，返回控制器或者控制器名称的服务
controllerAs：string，控制器别名。
parent：string/object，手动指定该状态的父级。
resolve：object，将会被注入controller去执行的函数，string,function>形式。
url：string，当前状态的对应url。
views：object，视图展示的配置。string,object>形式。
abstract：boolean，一个永远不会被激活的抽象的状态，但可以给其子级提供特性的继承。默认是true。
onEnter：function，当进入一个状态后的回调函数。
onExit：function，当退出一个状态后的回调函数。
reloadOnSearch：boolean，如果为false，那么当一个search/query参数改变时不会触发相同的状态，用于当你修改$location.search()的时候不想重新加载页面。默认为true。
data：object，任意对象数据，用于自定义配置。继承父级状态的data属性。换句话说，通过原型继承可以达到添加一个data数据从而整个树结构都能获取到。
params：url里的参数值，通过它可以实现页面间的参数传递。

    </code>
</pre>
        </section>


        <section>
            <h3>五.代码实战</h3>
        </section>


        <section>
            <h3>六.拓展思考</h3>
        </section>
        <section>
            <h3>路由怎么传参</h3>
            <a href="http://blog.csdn.net/baidu_31333625/article/details/62226816">angular1.x ui-route传参的三种写法</a><br/>

        </section>
        <section>
            <h3>七.参考文献</h3>
        </section>
        <section>

            <p><a href="http://www.html-js.com/article/Front-end-source-code-analysis-original-uirouter-source-code-analysis"> ui.router源码解析</a></p>
            <p><a href="http://www.open-open.com/lib/view/open1416878937309.html">AngularJS ui-router (嵌套路由)</a></p>
            <p><a href="http://www.cnblogs.com/liulangmao/p/4155015.html">angular的uiRouter服务学习</a></p>
            <p><a href="http://blog.csdn.net/qian_xiaona/article/details/50888212"> $stateParams服务 </a></p>
        </section>
        <section>
            <h3>八.更多讨论</h3>
        </section>
        <section>
            <h3>关于ui-router的使用大家还要什么技巧可以分享下</h3>
        </section>
        <section>
            <h4>鸣谢</h4>
            <p>感谢大家观看</p>
            <p>
                <small>鸣谢 : 杨涛</small>
            </p>
        </section>

    </div>
</div>

<script src="../lib/reveal/js/head.min.js"></script>
<script src="../lib/reveal/reveal.js"></script>

<script>

    // 以下为常见配置属性的默认值
    // {
    // 	controls: true, // 是否在右下角展示控制条
    // 	progress: true, // 是否显示演示的进度条
    // 	slideNumber: false, // 是否显示当前幻灯片的页数编号，也可以使用代码slideNumber: 'c / t' ，表示当前页/总页数。
    // 	history: false, // 是否将每个幻灯片改变加入到浏览器的历史记录中去
    // 	keyboard: true, // 是否启用键盘快捷键来导航
    // 	overview: true, // 是否启用幻灯片的概览模式，可使用"Esc"或"o"键来切换概览模式
    // 	center: true, // 是否将幻灯片垂直居中
    // 	touch: true, // 是否在触屏设备上启用触摸滑动切换
    // 	loop: false, // 是否循环演示
    // 	rtl: false, // 是否将演示的方向变成RTL，即从右往左
    // 	fragments: true, // 全局开启和关闭碎片。
    // 	autoSlide: 0, // 两个幻灯片之间自动切换的时间间隔（毫秒），当设置成 0 的时候则禁止自动切换，该值可以被幻灯片上的 ` data-autoslide` 属性覆盖
    // 	transition: 'default', // 切换过渡效果，有none/fade/slide/convex/concave/zoom
    // 	transitionSpeed: 'default', // 过渡速度，default/fast/slow
    // 	mouseWheel: true, //是否启用通过鼠标滚轮来切换幻灯片
    // }

    // 初始化幻灯片
    Reveal.initialize({
        history : true,
        dependencies : [
            {src : '../plugin/markdown/marked.js'},
            {src : '../plugin/markdown/markdown.js'},
            {src : '../plugin/notes/notes.js', async : true},
            {
                src : '../plugin/highlight/highlight.js',
                async : true,
                callback : function(){ hljs.initHighlightingOnLoad(); }
            }
        ]
    });
</script>
</body>
</html>
